package com.thiswhyme.redis.geo;

import com.thiswhyme.redis.geo.entity.DistanceMember;
import org.springframework.data.geo.Metrics;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * Geo 模版方法抽象类
 *
 * @author thiswhyme
 * @date 2022/11/4
 */
public abstract class AbstractGeoTemplate implements GeoTemplate{

    @Override
    public <T> Map<T, Double> radius(String key, double lng, double lat, double radius, Metrics metric) {
        return radius(key, lng, lat, radius, metric, null, null);
    }

    @Override
    public <T> Map<T, Double> radius(String key, double lng, double lat, double radius, Metrics metric, int count) {
        return radius(key, lng, lat, radius, metric, null, count);
    }

    @Override
    public <T> Map<T, Double> radius(String key, double lng, double lat, double radius, Metrics metric, boolean asc) {
        return radius(key, lng, lat, radius, metric, asc, null);
    }

    @Override
    public <T> Map<T, Double> radius(String key, T member, double radius, Metrics metric) {
        return radius(key, member, radius, metric, null, null);
    }

    @Override
    public <T> Map<T, Double> radius(String key, T member, double radius, Metrics metric, int count) {
        return radius(key, member, radius, metric, null, count);
    }

    @Override
    public <T> Map<T, Double> radius(String key, T member, double radius, Metrics metric, boolean asc) {
        return radius(key, member, radius, metric, asc, null);
    }

    @Override
    public <T> List<DistanceMember<T>> mapToSortedObject(Map<T, Double> memberMap, boolean asc) {
        if (CollectionUtils.isEmpty(memberMap)) {
            return Collections.emptyList();
        }
        List<DistanceMember<T>> list = new ArrayList<>(memberMap.size());
        memberMap.forEach((member, distance) ->
                list.add(new DistanceMember<>(distance, member)));
        if (asc) {
            list.sort(Comparator.comparing(DistanceMember<T>::getDistance));
        } else {
            list.sort(Comparator.comparing(DistanceMember<T>::getDistance).reversed());
        }
        return list;
    }
}

